import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.lang.Error
import java.net.URLDecoder
import java.util.*

/**
 * Author:  LuoHaoLun
 * Email :  506503279@qq.com
 * Date  :  2020/11/9
 */
object Start {

//    init {
//        Thread.setDefaultUncaughtExceptionHandler { t, e ->
//            e.printStackTrace()
//            while (true) {
//                Thread.sleep(1000)
//            }
//        }
//    }

    @JvmStatic
    fun main(args: Array<String>) {

        try {
            val dir = File(inputDir)
            if (!FileUtils.isDir(dir)) "同级目录找不到input文件夹".error()
            val listDir = dir.listFiles() ?: "input文件夹内容为空".error()
            FileUtils.delete(outputDir)
            FileUtils.createOrExistsDir(outputDir)
            "总共站场数：${listDir.size}".p()
            for ((num, stationDir) in listDir.withIndex()) {
                val files1 = stationDir.listFiles()?.ifEmpty { null } ?: "站场“${stationDir.name}”目录下没有数据".error()
                val files = files1.firstOrNull { it.isDirectory && it.name == "嗨格式" }?.listFiles()?.ifEmpty { null } ?: "站场“${stationDir.name}”目录下找不到嗨格式路径或路径中没数据".error()
                var templateName = ""
                try {
                    val guDaoList = files.firstOrNull { it.name.contains("股道表") }?.let {
                        templateName = it.nameWithoutExtension.let { it.replace("股道表", "") }
                        ReadManager.readGuDao(it)
                    } ?: "站场“${stationDir.name}”目录下找不到股道表".error()

                    val turnoutList = files.firstOrNull { it.name.contains("道岔表") }?.let { ReadManager.readTurnout(it) } ?: "站场“${stationDir.name}”目录下找不到道岔表".error()
                    val curveList = files.firstOrNull { it.name.contains("曲线表") }?.let { ReadManager.readCurve(it) } ?: "站场“${stationDir.name}”目录下找不到曲线表".error()


                    val csvList = mutableListOf<CSVBean>()
                    val mainGuDaoList = guDaoList.filter { it.lineType == "正线" }
                    for (exc in mainGuDaoList) {
                        val list = mutableListOf<CSVBean>()
                        if (exc.startNo.isNotEmpty())
                            list.add(CSVBean(guDaoNo = exc.guDaoNo, desc = exc.startNo))
                        list.addAll(exc.passNoList.map { CSVBean(guDaoNo = exc.guDaoNo, desc = it) })
                        if (exc.endNo.isNotEmpty())
                            list.add(CSVBean(guDaoNo = exc.guDaoNo, desc = exc.endNo))
                        csvList.addAll(list)
                    }

                    for (csv in csvList) {
                        val turnout = turnoutList.firstOrNull { it.turnoutNo == csv.desc } ?: continue
                        csv.startMileage = turnout.mileage.toDoubleOrNull() ?: 0.0
                    }

                    csvList.forEach {
                        it.guDaoNo = it.guDaoNo.changeNo { "股道$it" }
                        it.desc = it.desc.changeNo { "${it}#尖" }
                    }

                    turnoutList.forEach {
                        it.turnoutNo = it.turnoutNo.changeNo { "${it}#尖" }
                    }

                    val map = curveList.groupBy { it.guDaoNo }
                    for ((_, list) in map) {
                        list.forEachIndexed { index, it ->
                            it.guDaoNo += "-${index + 1}"
                        }
                    }


                    save(templateName, csvList, turnoutList, curveList)

                    "完成：${num + 1}".p()

                } catch (e: Exception) {
                    "站场“${stationDir.name}”${e.message}".error()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        while (true) {
            Thread.sleep(1000)
        }
    }
}

val inputDir by lazy { System.getProperty("user.dir") + "/input" }
val outputDir by lazy { System.getProperty("user.dir") + "/output" }

private fun save(fileName: String, csvList: List<CSVBean>, turnoutList: List<TurnoutExcel>, curveList: List<CurveExcel>) {
    val inputStream = Start::class.java.classLoader.getResourceAsStream("template.xlsx")
    val workbook = XSSFWorkbook(inputStream)
    val sheet0 = workbook.getSheetAt(0)
    csvList.forEachIndexed { index, it ->
        var col = 0
        sheet0.set(index + 1, col++, it.guDaoNo)
        sheet0.set(index + 1, col++, "")
        sheet0.set(index + 1, col++, it.desc)
        sheet0.set(index + 1, col++, it.startMileage)
        sheet0.set(index + 1, col++, "")
        sheet0.set(index + 1, col++, it.type)
    }

    val sheet1 = workbook.getSheetAt(1)
    turnoutList.forEachIndexed { index, it ->
        var col = 0
        sheet1.set(index + 1, col++, it.turnoutNo)
        sheet1.set(index + 1, col++, it.direction)
        sheet1.set(index + 1, col++, it.chartNo)
        sheet1.set(index + 1, col++, it.type)
        sheet1.set(index + 1, col++, it.mileage)
    }

    val sheet2 = workbook.getSheetAt(2)
    curveList.forEachIndexed { index, it ->
        var col = 0
        sheet2.set(index + 1, col++, it.guDaoNo)
        sheet2.set(index + 1, col++, it.direction)
        sheet2.set(index + 1, col++, it.r)
        sheet2.set(index + 1, col++, it.l)
        sheet2.set(index + 1, col++, it.alpha)
        sheet2.set(index + 1, col++, it.ls1)
        sheet2.set(index + 1, col++, it.ls2)
        sheet2.set(index + 1, col++, it.mark)
    }

    val out = FileOutputStream("${outputDir}/${fileName}.xlsx")
    workbook.write(out)
    out.close()
    workbook.close()
}


fun String.changeNo(block: (String) -> String): String {
    return if (this.toIntOrNull() == null) this else block(this)
}

fun Any.p() {
    println(this)
}

fun String.error(): Nothing {
    error(this)
}

fun uuid(): String {
    return UUID.randomUUID().toString().replace("-", "").toUpperCase().substring(0, 4)
}
